package gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import nonthreaded.PageAnalyzer;
import nonthreaded.PageParser;
import nonthreaded.PageRetriever;

/**
 * GUI Frame for Non-Threaded Crawler.
 * @author Daniel Anderson and Luc H. Le
 * @version TCSS422 2012
 */
@SuppressWarnings("serial")
public class NormalCrawlerFrame extends JFrame{
	
	//GUI stuff
	private List<String> my_keywords;
	private JFrame my_frame;
	private JLabel my_crawled_label;
	private int my_crawled;
	private JPanel my_panel;
	private JTextArea my_text_panel;
	private boolean my_started;
	private boolean my_stopped;
	
	//Crawler Stuff
	private int my_limit;
	PageRetriever my_retriever;
	PageParser my_parser;
	PageAnalyzer my_analyzer;
	
	
	
	
	public NormalCrawlerFrame(List<String> keywords, String url, int num_pages) {
		super();
		my_limit = num_pages;
		my_crawled = 0;
		my_keywords = keywords;
		my_frame = new JFrame("TCSS 422 Webcrawler: Non-Threaded");
		my_crawled_label = new JLabel("Number of Pages Crawled: " + my_crawled);
		my_panel = new JPanel();
		my_text_panel = new JTextArea();
		my_started = false;
		
		my_keywords = keywords;
		my_retriever = new PageRetriever();
		my_parser = new PageParser();
		my_analyzer = new PageAnalyzer();
		
		try {
			my_retriever.addURL(new URL(url));
		} catch (MalformedURLException e) {
			//This should be impossible.
			JOptionPane.showMessageDialog(my_frame, "Initial URL Invalid",  "URL Error", JOptionPane.ERROR_MESSAGE);
		}

	}
	
	public void start() {
		buildUI();
	}
	
	private void buildUI() {
		my_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		my_frame.setLayout(new BorderLayout());
		my_frame.add(my_crawled_label, BorderLayout.PAGE_START);
		
		JScrollPane text_scroll = new JScrollPane(my_text_panel);
		text_scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		text_scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		
		my_frame.add(text_scroll, BorderLayout.CENTER);
		my_frame.add(my_panel, BorderLayout.PAGE_END);
		
		
		JButton startb = new JButton("Start");
		
		startb.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if(!my_started){
					try {
						my_stopped = false;
						doCrawl();
					} catch (IOException e) {
						my_text_panel.setText("An Error has occured in doCrawl()");
					}
				} else {
					JOptionPane.showMessageDialog(my_frame, "Crawler is Already Running",  "Crawler", JOptionPane.ERROR_MESSAGE);
				}
			}
		});
		
		my_panel.add(startb);

		my_frame.setSize(800, 600);
		my_frame.setResizable(false);
		my_frame.setVisible(true);
	}
	
	private void doCrawl() throws IOException {
		
		long start = System.currentTimeMillis();
		while(!my_retriever.isEmpty() && !my_stopped && my_crawled < my_limit) {
			my_text_panel.paintImmediately(my_text_panel.getVisibleRect());
			
			URL next = my_retriever.getNextURL();
			my_text_panel.append("\nParsing " + next);
			
			my_text_panel.paintImmediately(my_text_panel.getVisibleRect());
			my_parser.parse(next);
			my_text_panel.append("\nSaving URLs from " + next);
			
			my_text_panel.paintImmediately(my_text_panel.getVisibleRect());
			my_retriever.addURLs(my_parser.getHyperlinks());
			my_text_panel.append("\nAnalyzing " + next);
			
			my_text_panel.paintImmediately(my_text_panel.getVisibleRect());
			my_analyzer.analyzePage(my_parser.getText(), my_parser.getHyperlinks().size());
			my_crawled++;
			my_crawled_label.setText("Number of Pages Crawled: " + my_crawled);
			my_text_panel.append("\nFinished!\n--\n");
			my_text_panel.setCaretPosition(my_text_panel.getText().length());
			my_crawled_label.paintImmediately(my_text_panel.getVisibleRect());
			my_text_panel.paintImmediately(my_text_panel.getVisibleRect());
			
			//TODO Make this jump to the bottom of the text panel?
		}
		long end = System.currentTimeMillis();
		long time = end-start;
		//print info
		
		
		my_text_panel.append("\n=================SINGLETHREADED STATS==================");
		my_text_panel.append("\nPages retrieved: " + my_retriever.getRetrievedCount());
		
		double avwords =  (double)my_analyzer.getWordCount()/my_parser.getParseCount();
		my_text_panel.append("\nAverage words per page: " + String.format("%.3g", avwords));
		
		double avurls = (double)my_analyzer.getNumURLs()/my_parser.getParseCount();
		my_text_panel.append("\nAverage urls per page: " + String.format("%.3g", avurls));
		my_text_panel.append("\nKeyword Stats:");
		for(String key : my_keywords) {
			double avhits = (double)my_analyzer.getStats(key).getHits()/my_parser.getParseCount();
			my_text_panel.append("\n" + key + "-  Average Hits per page: " + String.format("%.3g", avhits) + "  Total Hits: " + my_analyzer.getStats(key).getHits());
		}
		long avparse =  my_parser.getParseTime()/ my_parser.getParseCount();
		my_text_panel.append("\nAverage parse time per page: " + avparse + " milliseconds");
		my_text_panel.append("\nTotal running time: " + time + " milliseconds");
		
		
	}
	
}
